﻿/*
 * Copyright © 2025−2026 WEI.ZHOU (Willis) (Chengdu). All rights reserved.
 *
 * THIS SOURCE CODE IS PROPRIETARY AND CONFIDENTIAL.
 * It is the exclusive property of WEI.ZHOU (Willis) and may not be
 * used, copied, distributed, or disclosed outside of WEI.ZHOU (Willis)
 * without express written permission.
 *
 * This code is provided to WEI.ZHOU (Willis) under a limited,
 * non-transferable internal license, and is for use only with the author's
 * approved purposes. No external license is granted or implied.
 *
 * Any unauthorized use, reproduction, or distribution is strictly prohibited
 * and may result in severe civil and criminal penalties.
 */

using NLog;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;

// ReSharper disable MethodOverloadWithOptionalParameter

namespace Aore.Core.LogUtils;

public abstract class AppLog
{
  /// <summary>
  /// 日志
  /// </summary>
  private static readonly Logger _logger = LogManager.GetLogger("AppLog");
  
  /// <summary>
  /// 添加Log
  /// </summary>
  /// <param name="loglevel"></param>
  /// <param name="message"></param>
  /// <param name="method"></param>
  /// <param name="className"></param>
  /// <param name="line"></param>
  public static void AddLog(LogLevel loglevel, string message, [CallerMemberName] string method = "", [CallerFilePath] string className = "", [CallerLineNumber] int line = 0)
  {
    //Log信息
    string newClassName = Path.GetFileNameWithoutExtension(className);
    string logMessage = $"{newClassName} | {method} | {line} | {message}";
    AddLog(loglevel, logMessage);
  }

  /// <summary>
  /// 记录 Info Log
  /// </summary>
  /// <param name="message"></param>
  /// <param name="method"></param>
  /// <param name="className"></param>
  /// <param name="line"></param>
  public static void Info(string message, [CallerMemberName] string method = "", [CallerFilePath] string className = "", [CallerLineNumber] int line = 0)
  {
    //Log信息
    string newClassName = Path.GetFileNameWithoutExtension(className);
    string logMessage = $"{newClassName} | {method} | {line} | {message}";
    AddLog(LogLevel.Info, logMessage);
  }
  
  /// <summary>
  /// 记录 Info Log
  /// </summary>
  /// <param name="message"></param>
  /// <param name="exception"></param>
  /// <param name="method"></param>
  /// <param name="className"></param>
  /// <param name="line"></param>
  public static void Info(string message, Exception exception, [CallerMemberName] string method = "", [CallerFilePath] string className = "", [CallerLineNumber] int line = 0)
  {
    //Log信息
    string newClassName = Path.GetFileNameWithoutExtension(className);
    string logMessage = $"{newClassName} | {method} | {line} | {message}";
    string exceptionText = GetExceptionDetails(exception);
    AddLog(LogLevel.Info, logMessage + exceptionText);
  }
  
  /// <summary>
  /// 记录 Error Log
  /// </summary>
  /// <param name="message"></param>
  /// <param name="method"></param>
  /// <param name="className"></param>
  /// <param name="line"></param>
  public static void Error(string message, [CallerMemberName] string method = "", [CallerFilePath] string className = "", [CallerLineNumber] int line = 0)
  {
    //Log信息
    string newClassName = Path.GetFileNameWithoutExtension(className);
    string logMessage = $"{newClassName} | {method} | {line} | {message}";
    AddLog(LogLevel.Error, logMessage);
  }
  
  /// <summary>
  /// 记录 Error Log
  /// </summary>
  /// <param name="message"></param>
  /// <param name="exception"></param>
  /// <param name="method"></param>
  /// <param name="className"></param>
  /// <param name="line"></param>
  public static void Error(string message, Exception exception, [CallerMemberName] string method = "", [CallerFilePath] string className = "", [CallerLineNumber] int line = 0)
  {
    //Log信息
    string newClassName = Path.GetFileNameWithoutExtension(className);
    string logMessage = $"{newClassName} | {method} | {line} | {message}";
    string exceptionText = GetExceptionDetails(exception);
    AddLog(LogLevel.Error, logMessage + exceptionText);
  }
  
  /// <summary>
  /// 记录 Error Log
  /// </summary>
  /// <param name="exception"></param>
  /// <param name="method"></param>
  /// <param name="className"></param>
  /// <param name="line"></param>
  public static void Error(Exception exception, [CallerMemberName] string method = "", [CallerFilePath] string className = "", [CallerLineNumber] int line = 0)
  {
    //Log信息
    string newClassName = Path.GetFileNameWithoutExtension(className);
    string logMessage = $"{newClassName} | {method} | {line} | {exception.Message}";
    string exceptionText = GetExceptionDetails(exception);
    AddLog(LogLevel.Error, logMessage + exceptionText);
  }
  
  /// <summary>
  /// 记录 Trace Log
  /// </summary>
  /// <param name="message"></param>
  /// <param name="method"></param>
  /// <param name="className"></param>
  /// <param name="line"></param>
  public static void Trace(string message, [CallerMemberName] string method = "", [CallerFilePath] string className = "", [CallerLineNumber] int line = 0)
  {
    //Log信息
    string newClassName = Path.GetFileNameWithoutExtension(className);
    string logMessage = $"{newClassName} | {method} | {line} | {message}";
    AddLog(LogLevel.Trace, logMessage);
  }
  
  /// <summary>
  /// 记录 Trace Log
  /// </summary>
  /// <param name="message"></param>
  /// <param name="exception"></param>
  /// <param name="method"></param>
  /// <param name="className"></param>
  /// <param name="line"></param>
  public static void Trace(string message, Exception exception, [CallerMemberName] string method = "", [CallerFilePath] string className = "", [CallerLineNumber] int line = 0)
  {
    //Log信息
    string newClassName = Path.GetFileNameWithoutExtension(className);
    string logMessage = $"{newClassName} | {method} | {line} | {message}";
    string exceptionText = GetExceptionDetails(exception);
    AddLog(LogLevel.Trace, logMessage + exceptionText);
  }

  /// <summary>
  /// 记录 Warn Log
  /// </summary>
  /// <param name="message"></param>
  /// <param name="method"></param>
  /// <param name="className"></param>
  /// <param name="line"></param>
  public static void Warn(string message, [CallerMemberName] string method = "", [CallerFilePath] string className = "", [CallerLineNumber] int line = 0)
  {
    //Log信息
    string newClassName = Path.GetFileNameWithoutExtension(className);
    string logMessage = $"{newClassName} | {method} | {line} | {message}";
    AddLog(LogLevel.Warn, logMessage);
  }
  
  /// <summary>
  /// 记录 Warn Log
  /// </summary>
  /// <param name="message"></param>
  /// <param name="exception"></param>
  /// <param name="method"></param>
  /// <param name="className"></param>
  /// <param name="line"></param>
  public static void Warn(string message, Exception exception, [CallerMemberName] string method = "", [CallerFilePath] string className = "", [CallerLineNumber] int line = 0)
  {
    //Log信息
    string newClassName = Path.GetFileNameWithoutExtension(className);
    string logMessage = $"{newClassName} | {method} | {line} | {message}";
    string exceptionText = GetExceptionDetails(exception);
    AddLog(LogLevel.Warn, logMessage + exceptionText);
  }
  
  /// <summary>
  /// 记录 Debug Log
  /// </summary>
  /// <param name="message"></param>
  /// <param name="method"></param>
  /// <param name="className"></param>
  /// <param name="line"></param>
  public static void Debug(string message, [CallerMemberName] string method = "", [CallerFilePath] string className = "", [CallerLineNumber] int line = 0)
  {
    //Log信息
    string newClassName = Path.GetFileNameWithoutExtension(className);
    string logMessage = $"{newClassName} | {method} | {line} | {message}";
    AddLog(LogLevel.Debug, logMessage);
  }
  
  /// <summary>
  /// 记录 Debug Log
  /// </summary>
  /// <param name="message"></param>
  /// <param name="exception"></param>
  /// <param name="method"></param>
  /// <param name="className"></param>
  /// <param name="line"></param>
  public static void Debug(string message, Exception exception, [CallerMemberName] string method = "", [CallerFilePath] string className = "", [CallerLineNumber] int line = 0)
  {
    //Log信息
    string newClassName = Path.GetFileNameWithoutExtension(className);
    string logMessage = $"{newClassName} | {method} | {line} | {message}";
    string exceptionText = GetExceptionDetails(exception);
    AddLog(LogLevel.Debug, logMessage + exceptionText);
  }
  
  /// <summary>
  /// 记录 Fatal Log
  /// </summary>
  /// <param name="message"></param>
  /// <param name="method"></param>
  /// <param name="className"></param>
  /// <param name="line"></param>
  public static void Fatal(string message, [CallerMemberName] string method = "", [CallerFilePath] string className = "", [CallerLineNumber] int line = 0)
  {
    //Log信息
    string newClassName = Path.GetFileNameWithoutExtension(className);
    string logMessage = $"{newClassName} | {method} | {line} | {message}";
    AddLog(LogLevel.Fatal, logMessage);
  }
  
  /// <summary>
  /// 记录 Fatal Log
  /// </summary>
  /// <param name="message"></param>
  /// <param name="exception"></param>
  /// <param name="method"></param>
  /// <param name="className"></param>
  /// <param name="line"></param>
  public static void Fatal(string message, Exception exception, [CallerMemberName] string method = "", [CallerFilePath] string className = "", [CallerLineNumber] int line = 0)
  {
    //Log信息
    string newClassName = Path.GetFileNameWithoutExtension(className);
    string logMessage = $"{newClassName} | {method} | {line} | {message}";
    string exceptionText = GetExceptionDetails(exception);
    AddLog(LogLevel.Fatal, logMessage + exceptionText);
  }
  
  /// <summary>
  /// 添加Log
  /// </summary>
  /// <param name="loglevel">级别</param>
  /// <param name="strMsg">信息</param>
  private static void AddLog(LogLevel loglevel,string strMsg = "")
  {
    if (loglevel == LogLevel.Trace)
    {
      _logger.Trace(strMsg);
    }
    else if (loglevel == LogLevel.Info)
    {
      _logger.Info(strMsg);
    }
    else if (loglevel == LogLevel.Error)
    {
      _logger.Error(strMsg);
    }
    else if (loglevel == LogLevel.Warn)
    {
      _logger.Warn(strMsg);
    }
  }
  
  /// <summary>
  /// 提取异常类型、消息以及发生异常的类名、方法名、文件名和行号
  /// </summary>
  /// <param name="ex">Exception</param>
  /// <returns>显示异常日志</returns>
  private static string GetExceptionDetails(Exception ex)
  {
    try
    {
      StringBuilder exceptionDetails = new StringBuilder();

      // 异常类型与消息
      exceptionDetails.AppendLine();
      exceptionDetails.AppendLine($"\t\t\t\t\t\t\t\t\t\t\t\t\t\tException type: {ex.GetType().FullName}");
      exceptionDetails.Append($"\t\t\t\t\t\t\t\t\t\t\t\t\t\tException message: {ex.Message}");

      // 发生异常的方法名和行号（如果可用）
      if (ex.StackTrace != null)
      {
        StackTrace st = new StackTrace(ex, true);
        var frame = st.GetFrame(0);
        MethodBase? method = frame?.GetMethod();
        exceptionDetails.AppendLine();
        exceptionDetails.Append($"\t\t\t\t\t\t\t\t\t\t\t\t\t\tMethod: {method?.DeclaringType?.FullName}.{method?.Name}");
        exceptionDetails.AppendLine();
        exceptionDetails.AppendLine($"\t\t\t\t\t\t\t\t\t\t\t\t\t\tFile: {frame?.GetFileName()}");
        exceptionDetails.Append($"\t\t\t\t\t\t\t\t\t\t\t\t\t\tLine:  {frame?.GetFileLineNumber()}");
      }


      return exceptionDetails.ToString();
    }
    catch
    {
      return ex.Message;
    }
  }
}